#!/bin/bash
# ========================================================
# K3s 离线安装脚本 - 版本 1.33.1 (增强版)
# 功能：一键安装 K3s 集群（离线模式）及监控日志组件
# 特点：
#   - 支持安装前检查现有安装
#   - 支持彻底卸载旧版本
#   - 完全离线安装
#   - 自动配置 kubectl 和环境变量
#   - 卸载后提供继续安装或退出选项
#   - 集成 Prometheus+Grafana 监控
#   - 集成 Loki+Promtail 日志收集
# 文件要求：
#   - k3s 二进制文件
#   - k3s-airgap-images-amd64.tar.zst 镜像包
# 放置位置：当前目录
# ========================================================

# 定义版本号
K3S_VERSION="1.33.1"
SCRIPT_VERSION="v1.3.0"  # 更新版本号

# 定义颜色代码
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 无颜色

# 显示标题和版本信息
echo -e "${BLUE}"
echo "================================================================"
echo "K3s 离线安装脚本 (含监控与日志组件)"
echo "版本: ${K3S_VERSION} (脚本版本: ${SCRIPT_VERSION})"
echo "作者: 相框开发 团队"
echo "日期: $(date +'%Y-%m-%d %H:%M:%S')"
echo "================================================================"
echo -e "${NC}"

# 检查是否以 root 运行
if [ "$(id -u)" -ne 0 ]; then
    echo -e "${RED}错误: 此脚本必须以 root 用户运行${NC}"
    exit 1
fi

# 获取脚本所在目录
BASE_DIR=$(cd "$(dirname "$0")" && pwd)
echo -e "${GREEN}脚本运行目录: ${BASE_DIR}${NC}"

# 安装 Helm (用于部署监控和日志组件)
install_helm() {
    if ! command -v helm &> /dev/null; then
        echo -e "${YELLOW}>>> 安装 Helm...${NC}"
        curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
        chmod 700 get_helm.sh
        ./get_helm.sh
        rm get_helm.sh
        echo -e "${GREEN}Helm 安装成功${NC}"
    else
        echo -e "${GREEN}Helm 已安装${NC}"
    fi
}

# 安装监控组件 (Prometheus + Grafana)
install_monitoring() {
    echo -e "${YELLOW}>>> 安装监控组件 (Prometheus + Grafana)...${NC}"

    # 创建命名空间
    kubectl create namespace monitoring --dry-run=client -o yaml | kubectl apply -f -

    # 添加稳定的 Helm 仓库
    helm repo add stable https://charts.helm.sh/stable
    helm repo update

    # 安装 kube-state-metrics
    helm upgrade --install kube-state-metrics stable/kube-state-metrics \
        --namespace monitoring \
        --set image.repository=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-state-metrics \
        --set image.tag=v2.9.2

    # 安装 Prometheus
    helm upgrade --install prometheus stable/prometheus \
        --namespace monitoring \
        --set alertmanager.enabled=false \
        --set pushgateway.enabled=false \
        --set server.service.type=NodePort \
        --set server.service.nodePort=30900 \
        --set server.persistentVolume.size=10Gi \
        --set server.retention=7d

    # 安装 Grafana
    helm upgrade --install grafana stable/grafana \
        --namespace monitoring \
        --set service.type=NodePort \
        --set service.nodePort=30000 \
        --set adminPassword=admin \
        --set persistence.enabled=true \
        --set persistence.size=5Gi

    # 等待 Pod 就绪
    kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=grafana -n monitoring --timeout=300s
    kubectl wait --for=condition=ready pod -l app=prometheus -n monitoring --timeout=300s

    echo -e "${GREEN}监控组件安装完成${NC}"
}

# 安装日志组件 (Loki + Promtail)
install_logging() {
    echo -e "${YELLOW}>>> 安装日志组件 (Loki + Promtail)...${NC}"

    # 创建命名空间
    kubectl create namespace logging --dry-run=client -o yaml | kubectl apply -f -

    # 安装 Loki
    helm upgrade --install loki grafana/loki \
        --namespace logging \
        --set loki.persistence.enabled=true \
        --set loki.persistence.size=5Gi \
        --set loki.config.table_manager.retention_period=168h

    # 安装 Promtail
    helm upgrade --install promtail grafana/promtail \
        --namespace logging \
        --set config.lokiAddress="http://loki.logging:3100/loki/api/v1/push"

    # 等待 Pod 就绪
    kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=loki -n logging --timeout=300s

    echo -e "${GREEN}日志组件安装完成${NC}"
}

# 安装监控组件 (Prometheus + Grafana) - 离线版
install_monitoring_offline() {
    echo -e "${YELLOW}>>> 安装监控组件 (Prometheus + Grafana) - 离线版...${NC}"

    # 创建命名空间
    kubectl create namespace monitoring

    # 应用 CRD
    kubectl apply -f ${BASE_DIR}/monitoring/manifests/setup

    # 等待 CRD 就绪
    sleep 30

    # 应用主清单
    kubectl apply -f ${BASE_DIR}/monitoring/manifests/

    # 暴露 Grafana
    kubectl patch svc grafana -n monitoring -p '{"spec": {"type": "NodePort", "ports": [{"port": 3000, "nodePort": 30000}]}}'

    # 等待 Pod 就绪
    kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=grafana -n monitoring --timeout=300s
    kubectl wait --for=condition=ready pod -l app=prometheus -n monitoring --timeout=300s

    echo -e "${GREEN}监控组件安装完成${NC}"
}

# 安装日志组件 (Loki + Promtail) - 离线版
install_logging_offline() {
    echo -e "${YELLOW}>>> 安装日志组件 (Loki + Promtail) - 离线版...${NC}"

    # 创建命名空间
    kubectl create namespace logging

    # 应用 Loki
    kubectl apply -f ${BASE_DIR}/logging/production/loki.yaml -n logging

    # 应用 Promtail
    kubectl apply -f ${BASE_DIR}/logging/production/promtail.yaml -n logging

    # 等待 Pod 就绪
    kubectl wait --for=condition=ready pod -l app=loki -n logging --timeout=300s

    echo -e "${GREEN}日志组件安装完成${NC}"
}

# 检查是否已安装 K3s
check_existing_installation() {
    echo -e "${YELLOW}>>> 检查现有 K3s 安装...${NC}"

    local installed=false

    # 检查服务是否存在
    if systemctl list-unit-files | grep -q 'k3s.service'; then
        echo -e "${RED}检测到 K3s 服务已安装${NC}"
        installed=true
    fi

    # 检查二进制文件
    if [ -f "/usr/local/bin/k3s" ]; then
        echo -e "${RED}检测到 K3s 二进制文件存在${NC}"
        installed=true
    fi

    # 检查数据目录
    if [ -d "/var/lib/rancher/k3s" ]; then
        echo -e "${RED}检测到 K3s 数据目录存在${NC}"
        installed=true
    fi

    # 检查配置文件
    if [ -f "/etc/rancher/k3s/k3s.yaml" ]; then
        echo -e "${RED}检测到 K3s 配置文件存在${NC}"
        installed=true
    fi

    if [ "$installed" = true ]; then
        echo -e "${YELLOW}================================================================"
        echo "检测到系统上已存在 K3s 安装 (版本: ${K3S_VERSION})"
        echo "继续安装将覆盖现有安装并删除所有集群数据"
        echo "================================================================"
        echo -e "${NC}"

        while true; do
            read -p "是否要删除现有安装并继续? (y/n): " choice
            case "$choice" in
                y|Y )
                    uninstall_existing
                    # 卸载后询问是否继续安装
                    ask_continue_after_uninstall
                    break
                    ;;
                n|N )
                    echo -e "${GREEN}跳过 K3s 安装，继续执行其他步骤...${NC}"
                    export SKIP_K3S_INSTALL=true  # 添加标志变量
                    return 0
                    ;;
                * )
                    echo "无效输入，请输入 y 或 n"
                    ;;
            esac
        done
    else
        echo -e "${GREEN}未检测到现有 K3s 安装，继续安装${NC}"
        export SKIP_K3S_INSTALL=false
    fi
}

# 卸载后询问是否继续安装
ask_continue_after_uninstall() {
    echo -e "${YELLOW}================================================================"
    echo "现有 K3s 安装已成功卸载"
    echo "您可以选择:"
    echo "  1. 继续安装新的 K3s 集群"
    echo "  2. 退出安装脚本"
    echo "================================================================"
    echo -e "${NC}"

    while true; do
        read -p "请选择操作 (1/2): " choice
        case "$choice" in
            1 )
                echo -e "${GREEN}继续安装新的 K3s 集群...${NC}"
                return 0
                ;;
            2 )
                echo -e "${GREEN}退出安装脚本${NC}"
                exit 0
                ;;
            * )
                echo "无效输入，请输入 1 或 2"
                ;;
        esac
    done
}

# 卸载现有 K3s 安装
uninstall_existing() {
    echo -e "${YELLOW}>>> 开始卸载现有 K3s 安装...${NC}"

    # 尝试使用官方卸载脚本
    if [ -f "/usr/local/bin/k3s-uninstall.sh" ]; then
        echo -e "${YELLOW}使用官方卸载脚本...${NC}"
        /usr/local/bin/k3s-uninstall.sh
    elif [ -f "/usr/local/bin/k3s-agent-uninstall.sh" ]; then
        echo -e "${YELLOW}使用 Agent 卸载脚本...${NC}"
        /usr/local/bin/k3s-agent-uninstall.sh
    else
        echo -e "${YELLOW}未找到官方卸载脚本，执行手动卸载...${NC}"
        manual_uninstall
    fi

    # 额外清理
    echo -e "${YELLOW}执行额外清理...${NC}"
    cleanup_residual_files

    echo -e "${GREEN}>>> 现有 K3s 安装已成功卸载${NC}"
}

# 手动卸载
manual_uninstall() {
    # 停止服务
    systemctl stop k3s k3s-agent 2>/dev/null || true

    # 禁用服务
    systemctl disable k3s k3s-agent 2>/dev/null || true

    # 删除服务文件
    rm -f /etc/systemd/system/k3s*.service
    rm -f /etc/systemd/system/multi-user.target.wants/k3s*.service

    # 重新加载 systemd
    systemctl daemon-reload
    systemctl reset-failed
}

# 清理残留文件
cleanup_residual_files() {
    echo -e "${YELLOW}>>> 清理残留文件...${NC}"

    # 删除二进制文件
    rm -f /usr/local/bin/k3s
    rm -f /usr/local/bin/kubectl
    rm -f /usr/local/bin/crictl
    rm -f /usr/local/bin/ctr

    # 删除数据目录
    rm -rf /var/lib/rancher/k3s
    rm -rf /var/lib/kubelet

    # 删除配置文件
    rm -rf /etc/rancher/k3s

    # 删除网络配置
    rm -rf /var/run/flannel
    rm -rf /var/run/containerd
    rm -rf /var_/run/k3s

    # 清理 CNI 配置
    rm -rf /etc/cni/net.d

    # 清理 iptables 规则
    echo -e "${YELLOW}>>> 清理 iptables 规则...${NC}"
    iptables-save | grep -v KUBE- | grep -v CNI- | iptables-restore || true
    ip6tables-save | grep -v KUBE- | grep -v CNI- | ip6tables-restore || true

    # 安全清理进程 - 只杀死真正的K3s进程，不杀脚本自身
    echo -e "${YELLOW}>>> 清理残留进程...${NC}"
    SCRIPT_PID=$$
    # 获取所有k3s相关进程，排除当前脚本
    pids=$(pgrep -f 'k3s' | grep -v $SCRIPT_PID)

    if [ -n "$pids" ]; then
        echo -e "${YELLOW}终止残留的K3s进程:${NC} $pids"
        kill $pids 2>/dev/null || true
        # 等待进程退出
        sleep 2
    else
        echo -e "${GREEN}未发现残留的K3s进程${NC}"
    fi

    echo -e "${GREEN}>>> 清理完成${NC}"
}

# 安装依赖
install_dependencies() {
    echo -e "${YELLOW}>>> 安装必要依赖...${NC}"
    if ! command -v zstd &> /dev/null; then
        yum install -y zstd
        echo -e "${GREEN}zstd 安装成功${NC}"
    else
        echo "zstd 已安装"
    fi
}

# 验证文件
verify_files() {
    echo -e "${YELLOW}>>> 检查离线文件...${NC}"
    REQUIRED_FILES=("k3s" "k3s-airgap-images-amd64.tar.zst")
    MISSING_FILES=()

    for file in "${REQUIRED_FILES[@]}"; do
        if [ ! -f "${BASE_DIR}/${file}" ]; then
            MISSING_FILES+=("$file")
        fi
    done

    if [ ${#MISSING_FILES[@]} -gt 0 ]; then
        echo -e "${RED}错误：缺少必要文件：${NC}"
        printf " - %s\n" "${MISSING_FILES[@]}"
        echo "请将这些文件放入 ${BASE_DIR} 目录"
        exit 1
    else
        echo -e "${GREEN}所有必需文件已找到${NC}"
    fi
}

# 获取本机IP地址（优先使用内网地址）
get_local_ip() {
  # 尝试多种方法获取本机IP
  local ip
  ip=$(hostname -I 2>/dev/null | awk '{print $1}') || \
  ip=$(ip route get 1 | awk '{print $7; exit}' 2>/dev/null) || \
  ip=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n 1)

  echo "$ip"
}

# 配置私有镜像仓库
configure_private_registry() {
    echo -e "${YELLOW}>>> 配置私有镜像仓库...${NC}"

    # 创建必要的配置目录
    mkdir -p /etc/rancher/k3s

    # 尝试获取公网IP（带超时）
    PUBLIC_IP=$(curl -s --max-time 3 ifconfig.me 2>/dev/null || echo "")

    if [ -n "$PUBLIC_IP" ]; then
      DEFAULT_DOMAIN=$PUBLIC_IP
    else
      # 获取本机IP地址
      LOCAL_IP=$(get_local_ip)
      if [ -n "$LOCAL_IP" ]; then
        DEFAULT_DOMAIN=$LOCAL_IP
        echo "警告: 使用本机IP地址: $LOCAL_IP"
      else
        # 无法获取任何IP地址，退出安装
        echo "错误: 无法获取本机IP地址"
        echo "请手动设置 PRIVATE_REGISTRY 环境变量"
        echo "例如: export PRIVATE_REGISTRY='192.168.0.2'"
        exit 1
      fi
    fi

    # 提示用户输入域名
    read -p "请输入GitLab域名或IP地址（默认: $DEFAULT_DOMAIN）: " USER_DOMAIN
    export DOMAIN_NAME=${USER_DOMAIN:-$DEFAULT_DOMAIN}

    # 检查域名是否有效
    if ! [[ $DOMAIN_NAME =~ ^[a-zA-Z0-9.-]+$ ]]; then
        echo "错误: 输入的域名 '$DOMAIN_NAME' 不合法"
        exit 1
    fi

    echo "使用域名: $DOMAIN_NAME"

    # 创建 registries.yaml 配置文件
    cat > /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
  "$DOMAIN_NAME:5000":
    endpoint:
      - "http://$DOMAIN_NAME:5000"
EOF

    echo -e "${GREEN}私有镜像仓库配置完成${NC}"
}

# 准备安装
prepare_installation() {
    echo -e "${YELLOW}>>> 安装 K3s 二进制文件...${NC}"
    cp ${BASE_DIR}/k3s /usr/local/bin/
    chmod 755 /usr/local/bin/k3s
    echo -e "${GREEN}K3s 二进制文件已安装${NC}"

    echo -e "${YELLOW}>>> 准备容器镜像...${NC}"
    mkdir -p /var/lib/rancher/k3s/agent/images/
    cp ${BASE_DIR}/k3s-airgap-images-amd64.tar.zst /var/lib/rancher/k3s/agent/images/
    echo -e "${GREEN}容器镜像已复制${NC}"

    echo -e "${YELLOW}>>> 解压容器镜像（可能需要几分钟）...${NC}"
    unzstd -f /var/lib/rancher/k3s/agent/images/k3s-airgap-images-amd64.tar.zst -o /var/lib/rancher/k3s/agent/images/k3s-airgap-images-amd64.tar
    echo -e "${GREEN}容器镜像解压完成${NC}"

    # 添加私有 registry 配置
    configure_private_registry
}

# 执行安装
perform_installation() {
    echo -e "${YELLOW}>>> 获取安装脚本...${NC}"

    # 使用本地安装脚本
    if [ -f "${BASE_DIR}/k3s-install.sh" ]; then
        INSTALL_SCRIPT="${BASE_DIR}/k3s-install.sh"
        echo -e "${GREEN}使用本地安装脚本: ${INSTALL_SCRIPT}${NC}"
    else
        echo "请手动下载或上传安装脚本并放入 ${BASE_DIR} 目录"
        exit 1
    fi

    chmod +x $INSTALL_SCRIPT
    echo -e "${GREEN}安装脚本准备就绪${NC}"

    echo -e "${YELLOW}>>> 开始安装 K3s 集群 (版本: ${K3S_VERSION})...${NC}"
    echo -e "${YELLOW}    禁用 Traefik Ingress 控制器${NC}"
    echo -e "${YELLOW}    使用私有仓库配置: /etc/rancher/k3s/registries.yaml${NC}"
    echo -e "${YELLOW}================================================================"

    # 添加 --private-registry 参数
    INSTALL_K3S_SKIP_DOWNLOAD=true \
    INSTALL_K3S_EXEC="--disable traefik --disable servicelb --private-registry /etc/rancher/k3s/registries.yaml" \
    $INSTALL_SCRIPT

    # 检查安装结果
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}K3s 安装成功${NC}"
    else
        echo -e "${RED}K3s 安装失败${NC}"
        echo "请检查日志: journalctl -u k3s -n 50 --no-pager"
        exit 1
    fi
}

# 安装后配置
post_install_config() {
    # 等待服务启动
    echo -e "${YELLOW}>>> 等待 K3s 服务启动...${NC}"
    for i in {1..10}; do
        if systemctl is-active --quiet k3s; then
            echo -e "${GREEN}K3s 服务已启动${NC}"
            break
        fi
        echo "等待 K3s 启动 ($i/10)..."
        sleep 5
    done

    # 检查服务状态
    systemctl status k3s --no-pager || true

    # 配置 kubectl
    echo -e "${YELLOW}>>> 配置 kubectl...${NC}"
    if ! command -v kubectl &> /dev/null; then
        ln -s /usr/local/bin/k3s /usr/local/bin/kubectl
    fi

    # 设置命令补全
    mkdir -p /etc/bash_completion.d
    kubectl completion bash > /etc/bash_completion.d/kubectl 2>/dev/null || true
    source /etc/bash_completion.d/kubectl 2>/dev/null || true
    echo -e "${GREEN}kubectl 配置完成${NC}"

    # 创建快捷命令别名
    echo "alias k='kubectl'" >> /root/.bashrc
    echo "alias kgp='kubectl get pods -A'" >> /root/.bashrc
    echo "alias kgn='kubectl get nodes'" >> /root/.bashrc
    echo -e "${GREEN}命令别名已设置${NC}"

    # 保存 kubeconfig
    mkdir -p /root/.kube
    if [ -f "/etc/rancher/k3s/k3s.yaml" ]; then
        cp /etc/rancher/k3s/k3s.yaml /root/.kube/config
        chmod 600 /root/.kube/config
        sed -i 's/127.0.0.1/'"$(hostname -I | awk '{print $1}')"'/g' /root/.kube/config
        echo -e "${GREEN}Kubeconfig 已配置${NC}"
    else
        echo -e "${YELLOW}警告: 未找到 Kubeconfig 文件${NC}"
    fi

    # 添加私有 registry 验证
    echo -e "${YELLOW}>>> 验证私有镜像仓库配置...${NC}"
    sleep 5  # 给 containerd 时间加载配置

    if command -v crictl &> /dev/null; then
        echo -e "${GREEN}使用 crictl 检查 registry 配置...${NC}"
        crictl info | grep -A 10 registry
    else
        echo -e "${YELLOW}警告: crictl 未安装，无法验证 registry 配置${NC}"
    fi
}

# 安装监控和日志组件
install_monitoring_logging() {
    echo -e "${YELLOW}================================================================"
    echo "是否安装监控和日志组件？"
    echo "  1. 安装监控组件 (Prometheus + Grafana) - 在线版"
    echo "  2. 安装日志组件 (Loki + Promtail) - 在线版"
    echo "  3. 安装全部组件 - 在线版"
    echo "  4. 安装监控组件 (Prometheus + Grafana) - 离线版"
    echo "  5. 安装日志组件 (Loki + Promtail) - 离线版"
    echo "  6. 安装全部组件 - 离线版"
    echo "  7. 跳过安装"
    echo "================================================================"
    echo -e "${NC}"

    while true; do
        read -p "请选择操作 (1-7): " choice
        case "$choice" in
            1 )
                install_helm
                install_monitoring
                break
                ;;
            2 )
                install_helm
                install_logging
                break
                ;;
            3 )
                install_helm
                install_monitoring
                install_logging
                break
                ;;
            4 )
                install_monitoring_offline
                break
                ;;
            5 )
                install_logging_offline
                break
                ;;
            6 )
                install_monitoring_offline
                install_logging_offline
                break
                ;;
            7 )
                echo -e "${GREEN}跳过监控和日志组件安装${NC}"
                break
                ;;
            * )
                echo "无效输入，请输入 1-7"
                ;;
        esac
    done
}

# 显示安装结果
show_installation_result() {
    # 获取版本信息
    k3s_version_output=$(/usr/local/bin/k3s --version 2>/dev/null || echo "未知")
    k8s_version=$(kubectl version --short 2>/dev/null | grep Server | awk '{print $3}' || echo "未知")

    # 获取节点状态
    if command -v kubectl &> /dev/null; then
        node_status=$(kubectl get nodes -o jsonpath='{.items[0].status.conditions[?(@.type=="Ready")].status}' 2>/dev/null || echo "未知")
    else
        node_status="未知"
    fi

    echo ""
    echo -e "${GREEN}================================================================"
    echo "✅ K3s 安装完成!"
    echo "================================================================"
    echo "集群信息："
    echo "  - 脚本版本: ${SCRIPT_VERSION}"
    echo "  - K3s 版本: ${K3S_VERSION}"
    echo "  - 安装时间: $(date +'%Y-%m-%d %H:%M:%S')"
    echo "  - Kubernetes 版本: ${k8s_version}"
    echo "  - 节点状态: ${node_status}"
    echo ""
    echo "管理命令:"
    echo "  - 启动/停止: systemctl start|stop k3s"
    echo "  - 查看状态: systemctl status k3s"
    echo "  - 查看日志: journalctl -u k3s -f"
    echo ""
    echo "Kubernetes 操作:"
    echo "  - 查看节点: kubectl get nodes"
    echo "  - 查看所有资源: kubectl get all -A"
    echo "  - 查看服务: kubectl get svc -A"

    # 显示监控组件信息
    if kubectl get pods -n monitoring &> /dev/null; then
        echo ""
        echo -e "${GREEN}监控组件信息:${NC}"
        echo "Grafana URL: http://$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}'):30000"
        echo "用户名: admin"
        echo "密码: admin"
        echo "  - Prometheus URL: http://$(kubectl get svc kube-prometheus-prometheus -n monitoring -o jsonpath='{.spec.clusterIP}'):9090"
    fi

    # 显示日志组件信息
    if kubectl get pods -n logging &> /dev/null; then
        echo ""
        echo -e "${GREEN}日志组件信息:${NC}"
        echo "  - Loki URL: http://$(kubectl get svc loki -n logging -o jsonpath='{.spec.clusterIP}'):3100"
        echo "  - 查看日志: kubectl logs -l app=promtail -n logging"
    fi

    echo ""
    echo "注意：Traefik Ingress 控制器已被禁用"
    echo "================================================================"
    echo "后续步骤："
    echo "1. 安装网络插件（如果需要，默认已安装 Flannel）"
    echo "2. 安装其他 Ingress 控制器（如 Nginx Ingress）"
    echo "3. 部署应用程序"
    echo "================================================================"
    echo -e "${NC}"

    # 显示 kubeconfig 位置
    if [ -f "/root/.kube/config" ]; then
        echo "Kubeconfig 文件位置: /root/.kube/config"
        echo "使用以下命令配置访问:"
        echo "  export KUBECONFIG=/root/.kube/config"
    fi

    # 保存安装信息
    echo "K3s 版本: ${K3S_VERSION}" > /root/k3s-install-info.txt
    echo "安装时间: $(date)" >> /root/k3s-install-info.txt
    echo "节点名称: $(hostname)" >> /root/k3s-install-info.txt
    echo "IP 地址: $(hostname -I | awk '{print $1}')" >> /root/k3s-install-info.txt
}

create_gitlab_service_account() {
    echo -e "${YELLOW}>>> 创建 GitLab 服务账号...${NC}"

    # 创建命名空间
    kubectl create namespace gitlab-managed-apps --dry-run=client -o yaml | kubectl apply -f -

    # 创建服务账号和角色绑定
    cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: gitlab
  namespace: gitlab-managed-apps
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: gitlab-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: gitlab
  namespace: gitlab-managed-apps
EOF

    # 使用TokenRequest API创建Token（推荐方式）
    echo -e "${YELLOW}>>> 创建服务账号 Token...${NC}"
    GITLAB_TOKEN=$(kubectl create token gitlab -n gitlab-managed-apps --duration=8760h)

    if [ -z "$GITLAB_TOKEN" ]; then
        echo -e "${RED}错误：无法创建服务账号 Token${NC}"
        echo "请检查以下可能原因:"
        echo "1. Kubernetes 版本是否低于 v1.22"
        echo "2. 服务账号是否成功创建"
        echo "3. RBAC 权限是否正确"
        return 1
    fi

    echo -e "${GREEN}GitLab 服务账号 Token 创建成功${NC}"
    export GITLAB_TOKEN

    # 保存 Token 到文件
    echo "$GITLAB_TOKEN" > "${BASE_DIR}/gitlab_k8s_token.txt"
    chmod 600 "${BASE_DIR}/gitlab_k8s_token.txt"
    echo -e "${GREEN}Token 已保存到: ${BASE_DIR}/gitlab_k8s_token.txt${NC}"
}

# 调用 auto-register-runner.sh
call_auto_register_runner() {
    echo -e "${YELLOW}>>> 调用 auto-register-runner.sh 进行其他模块安装...${NC}"

    if [ ! -f "${BASE_DIR}/auto-register-runner.sh" ]; then
        echo -e "${RED}错误: 未找到 auto-register-runner.sh 脚本${NC}"
        return 1
    fi

    # 传递参数
    echo -e "${GREEN}传递参数:"
    echo "  - 域名: ${DOMAIN_NAME}"
    echo "  - Kubernetes Token: ${GITLAB_TOKEN}"
    echo "  - 数据目录: ${BASE_DIR}"
    echo -e "${NC}"

    chmod +x ${BASE_DIR}/auto-register-runner.sh

    # 执行脚本并传递参数
    ${BASE_DIR}/auto-register-runner.sh \
            --domain "${DOMAIN_NAME}" \
            --k8s-token "${GITLAB_TOKEN}" \
            --data-root "${BASE_DIR}"

    if [ $? -eq 0 ]; then
        echo -e "${GREEN}auto-register-runner.sh 执行成功${NC}"
    else
        echo -e "${RED}auto-register-runner.sh 执行失败${NC}"
    fi
}

# 调用 k8s-utils.sh k8s-tools Dockerfile gitlab打包工具镜像创建
call_k8s_utils() {
    echo -e "${YELLOW}>>> 调用 k8s-utils.sh 构建k8s-tools gitlab打包工具镜像创建...${NC}"

    if [ ! -f "${BASE_DIR}/k8s-utils.sh" ]; then
        echo -e "${RED}错误: 未找到 k8s-utils.sh 脚本${NC}"
        return 1
    fi

    # 确保脚本可执行
    chmod +x ${BASE_DIR}/k8s-utils.sh

    # 执行脚本并传递参数
    ${BASE_DIR}/k8s-utils.sh

    if [ $? -eq 0 ]; then
        echo -e "${GREEN}k8s-utils.sh 执行成功${NC}"
    else
        echo -e "${RED}k8s-utils.sh 执行失败${NC}"
    fi
}

# 主安装流程
main() {
    echo -e "${YELLOW}>>> 开始 K3s 安装流程 (版本: ${K3S_VERSION})${NC}"

    # 1. 检查现有安装
    check_existing_installation

    # 添加条件判断：仅当未跳过K3s安装时执行以下步骤
    if [ "$SKIP_K3S_INSTALL" != "true" ]; then
        # 2. 安装依赖
        install_dependencies

        # 3. 验证文件
        verify_files

        # 4. 准备安装
        prepare_installation

        # 5. 执行安装
        perform_installation

        # 6. 安装后配置
        post_install_config
    else
        echo -e "${YELLOW}>>> 跳过 K3s 安装步骤...${NC}"
    fi

    # 7. 安装监控和日志组件
    install_monitoring_logging

    # 8. 创建 GitLab 服务账号
    create_gitlab_service_account

    # 9. 调用 auto-register-runner.sh
    call_auto_register_runner

    # 10. 创建打包镜像工具
    call_k8s_utils

    # 11. 显示结果
    show_installation_result

    echo -e "${GREEN}>>> K3s 安装完成 (版本: ${K3S_VERSION})${NC}"
}

# 执行主函数
main